package com.ericsson.enap.modules.kpi.service;

import com.ericsson.common.pojo.FTPInfoVO;
import com.ericsson.common.util.DateUtils;
import com.ericsson.common.util.SFtpCarrierUtil;
import com.ericsson.enap.modules.kpi.entity.ImsNbiKpi;
import com.ericsson.enap.modules.kpi.entity.KpiNbiMeasInfo;
import com.ericsson.enap.modules.kpi.entity.KpiNbiMeasValue;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;

import java.io.File;
import java.util.*;

/**
 * 网元指标业务逻辑处理
 */
public interface KpiNbiFileProcess {
    /**
     * 网元类型
     */
    enum NetType {
        TAS,PSBCC,CSCF
    }

//    /**
//     * 通过FTP方式下载指标文件或向网元发送指令获取log文件
//     * @param IMSNetElement
//     * @param localDir
//     * @param date
//     * @param delay
//     * @param log
//     * @return
//     * @throws Exception
//     */
//    default List<File> download(IMSNetElement imsNetElement, String localDir, Date date, int delay, Logger log,String typeStr) throws Exception {
//        log.info("===================================================  start download Files");
//        String beginTime = DateUtils.getStatisTime(delay+30,date);
//        String time[]=beginTime.split("\\.");
//        FTPInfoVO ftpInfo = new FTPInfoVO();
//        ftpInfo.setHost(imsNetElement.getIpadr());
//        ftpInfo.setUserName(imsNetElement.getUsername());
//        ftpInfo.setPassword(imsNetElement.getPassword());
//        ftpInfo.setPath(imsNetElement.getDownloadPath()+"/"+time[0]+time[1]+"/");
//        ftpInfo.setPort(21);
//
//        List<File> fileList = new ArrayList<File>();
//        FtpCarrierUtil ftpCarrier = new FtpCarrierUtil(ftpInfo, log);
//        ftpCarrier.connect();
//        FTPClient ftpClient = ftpCarrier.getFtpClient();
//        ftpClient.changeWorkingDirectory(ftpInfo.getPath());
//        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//        FTPFile[] ftpFiles = ftpClient.listFiles();
//        for (int i = 0; i < ftpFiles.length; i++) {
//            FTPFile ftpFile = ftpFiles[i];
//            if (ftpFile.getName().length() > 14 && ftpFile.getName().contains(beginTime.replace(".",""))
//                    && ftpFile.getName().contains(typeStr)) {
//                String originalName = new String(ftpFile.getName().getBytes("ISO-8859-1"), "UTF-8");
//                File storeDir = FileUtil.newDirs(localDir);
//                File localFile = new File(storeDir, originalName);
//                if (!localFile.exists()) {
//                    OutputStream outputStream = new FileOutputStream(localFile);
//                    ftpClient.retrieveFile(ftpFile.getName(), outputStream);
//                    outputStream.flush();
//                    outputStream.close();
//                }
//                log.info("  ====================== download File ==========================  "+localFile.getName()+"  "+localFile.exists());
//                fileList.add(localFile);
//            }
//        }
//        ftpCarrier.close();
//        log.info(" ====================== end download Files ========================== "+fileList.size() +"  " +fileList.get(0).getName());
//        return fileList;
//    }

    default List<File> download(ImsNbiKpi imsNbiKpi, String localDir, Date date, int delay, Logger log, String typeStr) throws Exception {
        log.info("===================================================  start download Files");
        String beginTime = DateUtils.getStatisTime(delay+30,date,"yyyyMMdd.HH.mm.00");
        String time[]=beginTime.split("\\.");
        FTPInfoVO ftpInfo = new FTPInfoVO();
        ftpInfo.setHost(imsNbiKpi.getIp4());
        ftpInfo.setUserName(imsNbiKpi.getUsername());
        ftpInfo.setPassword(imsNbiKpi.getPassword());
        ftpInfo.setPath(imsNbiKpi.getDownloadPath()+"/"+time[0]+time[1]+"/");
        ftpInfo.setPort(21);
        List<File> fileList = new ArrayList<File>();
        SFtpCarrierUtil sftpCarrier = new SFtpCarrierUtil(ftpInfo, log);
        try {
            sftpCarrier.connect();
            Vector v = sftpCarrier.listFiles(ftpInfo.getPath());
            if (v.size() > 0) {
                Iterator it = v.iterator();
                while (it.hasNext()) {
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) it.next();
                    String filename = entry.getFilename();
                    SftpATTRS attrs = entry.getAttrs();
                    if (!attrs.isDir()) {
                        if (filename.length() > 14 && filename.contains(beginTime.replace(".",""))
                                && filename.contains(typeStr)) {
                            File tempFile=sftpCarrier.downloadFileKpi(ftpInfo.getPath(), filename, localDir, filename);
                            if(null!=tempFile) {
                                fileList.add(tempFile);
                            }
                        }
                    }
                }
            }
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            sftpCarrier.disconnect();
        }
        return fileList;
    }

    /**
     * 解析文件
     * @param filePath
     * @param log
     * @return
     */
    default Object analysis(String filePath, Logger log,List<String> formulaUnit){
        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(new File(filePath));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        List<?> measurements = doc.getRootElement().elements("Measurements");
        String beginTime = doc.getRootElement().element("FileHeader").element("StartTime").getText();
        beginTime = beginTime.replace("T", " ");
        List<KpiNbiMeasInfo> meansInfoList = new ArrayList<>();
        //循环Measurements级别
        for (Iterator<?> it = measurements.iterator(); it.hasNext();) {
            Element measInfoElement = (Element) it.next();
            //判断是否需要解析的空间粒度
            if(formulaUnit.contains(measInfoElement.element("ObjectType").getTextTrim())){
                //解析PmName
                Element pmNameElement=measInfoElement.element("PmName");
                List<?> nameList=pmNameElement.elements("N");
                //用于存储Pmname key存储 <N> text ;value存储 i
                Map<String,String> nameMap=new HashMap<>();
                for (Iterator<?> name = nameList.iterator(); name.hasNext();) {
                    Element nameElement = (Element) name.next();
                    nameMap.put(nameElement.getTextTrim(),nameElement.attributeValue("i"));
                }

                Element pmValueElement=measInfoElement.element("PmData");
                List<?> objectList=pmValueElement.elements("Object");
                for (Iterator<?> object = objectList.iterator(); object.hasNext();) {
                    KpiNbiMeasInfo measInfo=new KpiNbiMeasInfo();
                    //解析PmValue
                    //用于存储PmData key存储 i text ;value存储 i
                    Map<String, KpiNbiMeasValue> measValueMap = new HashMap<>();
                    Element valueElement = (Element) object.next();
                    //解析V节点
                    List<?> vList = valueElement.elements("V");
                    for (Iterator<?> value = vList.iterator(); value.hasNext(); ) {
                        KpiNbiMeasValue measValue = new KpiNbiMeasValue();
                        Map<String, String> vString = new HashMap<>();
                        Element v = (Element) value.next();
                        vString.put(v.attributeValue("i"), v.getTextTrim());
                        measValue.setVMap(vString);
                        measValueMap.put(v.attributeValue("i"), measValue);
                    }
                    //解析CV节点
                    List<?> cvList = valueElement.elements("CV");
                    for (Iterator<?> cValue = cvList.iterator(); cValue.hasNext(); ) {
                        KpiNbiMeasValue measValue = new KpiNbiMeasValue();
                        measValue.setCv(true);
                        Map<String, String> cvString = new HashMap<>();
                        Element cv = (Element) cValue.next();
                        for (Iterator<?> sValue = cv.elementIterator(); sValue.hasNext(); ) {
                            Element sn = (Element) sValue.next();
                            Element sv = (Element) sValue.next();
                            cvString.put(sn.getTextTrim(), sv.getTextTrim());
                        }
                        measValue.setVMap(cvString);
                        measValueMap.put(cv.attributeValue("i"), measValue);
                    }
                    //将解析结果添加到集合中
                    measInfo.setDn(valueElement.attributeValue("Dn").split(",")[2].replace("ManagedElement=",""));
                    measInfo.setBeginTime(beginTime);
                    measInfo.setMeasValueMap(measValueMap);
                    measInfo.setMeasTypeMap(nameMap);
                    measInfo.setObjectType(measInfoElement.element("ObjectType").getTextTrim());
                    meansInfoList.add(measInfo);
                }
            }
        }
        return meansInfoList;
    }
    /**
     * 是否需要解压
     * @return
     */
    boolean needUncompress();

    /**
     * 返回网元类型
     * @return
     */
    NetType getNetType();
}
